package club.kingyin.easycache.method.core;

import club.kingyin.easycache.cache.CacheAdapter;
import club.kingyin.easycache.cache.ValueSerializer;
import club.kingyin.easycache.cache.inner.InnerCache;
import club.kingyin.easycache.component.handler.Serializer;
import club.kingyin.easycache.proxy.CglibObjectFactory;
import club.kingyin.easycache.proxy.adapter.CacheMethodKeyAdapter;
import com.github.houbb.cache.core.support.load.CacheLoads;
import com.github.houbb.cache.core.support.persist.CachePersists;

import java.io.File;

// 代理类增强器
public class ProxyCacheEnhancer extends CacheEnhancer {

    private String path;

    private CacheMethodKeyAdapter cacheMethodKeyAdapter = null;

    public void setCacheMethodKeyAdapter(CacheMethodKeyAdapter cacheMethodKeyAdapter) {
        this.cacheMethodKeyAdapter = cacheMethodKeyAdapter;
    }

    public ProxyCacheEnhancer() {
        super();
    }

    public ProxyCacheEnhancer(CacheAdapter cacheAdapter, ValueSerializer serializer) {
        setDatabase(cacheAdapter);
        setSerializer(serializer);
    }

    public ProxyCacheEnhancer(String path, ValueSerializer serializer) {
        setSerializer(serializer);
        this.path = path;
    }

    @Override
    protected void init() {
        // 初始化引擎和序列化器
        loadCacheEngineAndSerializer();
        // 初始化缓存处理器
    }

    public Object proxy(Object target) {
        return CglibObjectFactory.proxyObjectFactory(target, this, getInvokePostProcessor(),cacheMethodKeyAdapter);
    }

    private void loadCacheEngineAndSerializer() {
        if (!isLoadSerializer()) {
            setSerializer(Serializer.GSON);
        }
        if (!isLoadDatabase()) {
            setDatabase(structureDefaultCacheEngine());
        }
    }

    private boolean isLoadSerializer() {
        return getSerializer() != null;
    }

    private CacheAdapter structureDefaultCacheEngine() {
        InnerCache.Builder builder = new InnerCache.Builder();
        if (new File(getPath()).exists()) {
            // 需要加载数据
            builder.load(CacheLoads.dbJson(getPath()));
        }
        InnerCache adapter = builder
                .persist(CachePersists.dbJson(getPath())).build();
        adapter.setSerializer(getSerializer());
        return adapter;
    }

    public String getPath() {
        return path = path == null ? defaultDbPath() : path;
    }

    public String defaultDbPath() {
        return System.getProperty("user.dir") + "/src/main/resources/easycache.rdb";
    }

    boolean isLoadDatabase() {
        return getDatabase() != null;
    }

    public CacheAdapter getDatabase() {
        return this.database;
    }

}
